﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ImobitechModel.com.Constantes;
using ImobitechModel.Facade;
using ImobitechDao;

namespace ImobitechModel.com.Controller
{
    public class ControladorImovel
    {
        public Object retornaImoveis(IDictionary<string, string> values)
        {
            ImovelFacade imovelFacade = ImovelFacade.getInstance();
            return imovelFacade.retornaImoveis();
        }

        public Object retornaImovel(IDictionary<string, string> values)
        {
            int id = int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelId).Value);
            ImovelFacade ImovelFacade = ImovelFacade.getInstance();
            Imovel imovel = (Imovel)ImovelFacade.retornaImovel(id);

            IDictionary<string, string> imovelRetorno = new Dictionary<string, string>();

            imovelRetorno.Add(NomeCampoConstantes.campo_ImovelId, imovel.Id.ToString());
            imovelRetorno.Add(NomeCampoConstantes.campo_ImovelBairro, imovel.Bairro);
            imovelRetorno.Add(NomeCampoConstantes.campo_ImovelCidade, imovel.Cidade);
            imovelRetorno.Add(NomeCampoConstantes.campo_ImovelEndereco, imovel.Endereço);
            imovelRetorno.Add(NomeCampoConstantes.campo_ImovelComplemento, imovel.Complemento);
            imovelRetorno.Add(NomeCampoConstantes.campo_ImovelReferencia, imovel.Referencia);
            imovelRetorno.Add(NomeCampoConstantes.campo_ImovelQuartos, imovel.Quartos.ToString());
            imovelRetorno.Add(NomeCampoConstantes.campo_ImovelExisteSuite, imovel.Suite.ToString());
            imovelRetorno.Add(NomeCampoConstantes.campo_ImovelQuartosSuite, imovel.QuartosSuite != null ? imovel.QuartosSuite.ToString() : "");
            imovelRetorno.Add(NomeCampoConstantes.campo_ImovelExisteGaragem, imovel.Garagem.ToString());
            imovelRetorno.Add(NomeCampoConstantes.campo_ImovelNumeroGaragem, imovel.NumeroGaragem != null ? imovel.NumeroGaragem.ToString() : "");
            imovelRetorno.Add(NomeCampoConstantes.campo_ImovelAreaPrivada, imovel.AreaPrivada.ToString());
            imovelRetorno.Add(NomeCampoConstantes.campo_ImovelAreaTotal, imovel.AreaTotal.ToString());
            return imovelRetorno;
        }

        public Object retornaImovel(int id)
        {
            ImovelFacade ImovelFacade = ImovelFacade.getInstance();
            return ImovelFacade.retornaImovel(id);
        }

        public Object inserirImovel(IDictionary<string, string> values, int idPessoa)
        {
            Imovel imovel = new Imovel();

            imovel.Bairro = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelBairro).Value;
            imovel.Cidade = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelCidade).Value;
            imovel.Endereço = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelEndereco).Value;
            imovel.Complemento = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelComplemento).Value;
            imovel.Referencia = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelReferencia).Value;
            imovel.Estado = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelEstado).Value;

            imovel.Quartos = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelQuartos).Value != "" ?
                int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelQuartos).Value) : 0;

            imovel.Suite = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelExisteSuite).Value != "" ?
                bool.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelExisteSuite).Value) : false;

            imovel.QuartosSuite = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelQuartosSuite).Value != "" ?
                int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelQuartosSuite).Value) : 0;

            imovel.Garagem = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelExisteGaragem).Value != "" ?
                bool.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelExisteGaragem).Value) : false;

            imovel.NumeroGaragem = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelNumeroGaragem).Value != "" ?
                int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelNumeroGaragem).Value) : 0;

            imovel.AreaTotal = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelAreaTotal).Value != "" ?
                int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelAreaTotal).Value) : 0;
            imovel.AreaPrivada = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelAreaPrivada).Value != "" ?
                int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelAreaPrivada).Value) : 0;


            string[] idDependencias = values.First(p => p.Key == NomeCampoConstantes.campo_dependencias).Value.Split(',');

            for (int i = 0; i < idDependencias.Count() - 1; i++)
            {
                Dependencias dependencia = (Dependencias)retornaDependencia(int.Parse(idDependencias[i]));
                Imovel_Dependencia imovelDependencia = new Imovel_Dependencia();
                imovelDependencia.Dependencias = dependencia;
                imovel.Imovel_Dependencia.Add(imovelDependencia);
            }

            ImovelFacade ImovelFacade = ImovelFacade.getInstance();
            imovel.Tipo_Imovel = (Tipo_Imovel)ImovelFacade.retornaTipoImovel(int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelTipoImovel).Value));

            Pessoa_Papel_Imovel pessoaImovel = new Pessoa_Papel_Imovel();

            PerfilFacade _perfilFacade = PerfilFacade.getInstance();
            Pessoa pessoa = (Pessoa)_perfilFacade.retornaPessoa(idPessoa);

            pessoaImovel.Pessoa_Papel = pessoa.Pessoa_Papel.First(p => p.Papel.Nome == "Dono");

            imovel.Pessoa_Papel_Imovel.Add(pessoaImovel);

            imovel.Anuncio.Add(criarAnuncio(imovel, int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelTipoAnuncio).Value),
                values.First(p => p.Key == NomeCampoConstantes.campo_TipoImovelDescricao).Value,
                values.First(p => p.Key == NomeCampoConstantes.campo_TipoImovelDescricaoCurta).Value,
                double.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_TipoImovelValor).Value)));

            ImovelFacade.inserirImovel(imovel);
            return imovel.Id;
        }

        public Object editarImovel(IDictionary<string, string> values)
        {
            Imovel imovel = (Imovel)retornaImovel(int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelId).Value));

            imovel.Bairro = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelBairro).Value;
            imovel.Cidade = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelCidade).Value;
            imovel.Endereço = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelEndereco).Value;
            imovel.Complemento = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelComplemento).Value;
            imovel.Referencia = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelReferencia).Value;
            imovel.Estado = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelEstado).Value;

            imovel.Quartos = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelQuartos).Value != "" ?
                int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelQuartos).Value) : 0;

            imovel.Suite = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelExisteSuite).Value != "" ?
                bool.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelExisteSuite).Value) : false;

            imovel.QuartosSuite = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelQuartosSuite).Value != "" ?
                int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelQuartosSuite).Value) : 0;

            imovel.Garagem = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelExisteGaragem).Value != "" ?
                bool.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelExisteGaragem).Value) : false;

            imovel.NumeroGaragem = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelNumeroGaragem).Value != "" ?
                int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelNumeroGaragem).Value) : 0;

            imovel.AreaTotal = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelAreaTotal).Value != "" ?
                int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelAreaTotal).Value) : 0;
            imovel.AreaPrivada = values.First(p => p.Key == NomeCampoConstantes.campo_ImovelAreaPrivada).Value != "" ?
                int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelAreaPrivada).Value) : 0;

            ImovelFacade ImovelFacade = ImovelFacade.getInstance();
            imovel.Tipo_Imovel = (Tipo_Imovel)ImovelFacade.retornaTipoImovel(int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelTipoImovel).Value));

            string[] idDependencias = values.First(p => p.Key == NomeCampoConstantes.campo_dependencias).Value.Split(',');
            List<Imovel_Dependencia> lista = imovel.Imovel_Dependencia.ToList();

            //foreach (Imovel_Dependencia dependenciaRemove in lista)\\
            for (int index = 0; index < lista.Count; index++)
                imovel.Imovel_Dependencia.Remove(lista[index]);

            //ImovelFacade.editaImovel(imovel);

            for (int i = 0; i < idDependencias.Count() - 1; i++)
            {
                Dependencias dependencia = (Dependencias)retornaDependencia(int.Parse(idDependencias[i]));
                Imovel_Dependencia imovelDependencia = new Imovel_Dependencia();
                imovelDependencia.Dependencias = dependencia;
                imovel.Imovel_Dependencia.Add(imovelDependencia);
            }
                        
            //imovel.Tipo_Imovel = (Tipo_Imovel)ImovelFacade.retornaTipoImovel(int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_ImovelAreaPrivada).Value));

            //ImovelFacade ImovelFacade = ImovelFacade.getInstance();
            ImovelFacade.editaImovel(imovel);
            return imovel.Id;
        }

        public Object retornaDependencias()
        {
            ImovelFacade imovelFacade = ImovelFacade.getInstance();

            List<Dependencias> dependencias = (List<Dependencias>)imovelFacade.retornaDependencias();
            IDictionary<string, string> dependenciasRetorno = new Dictionary<string, string>();

            for (int i = 0; i < dependencias.Count; i++)
                dependenciasRetorno.Add(dependencias[i].Id.ToString(), dependencias[i].descricao);

            return dependenciasRetorno;
        }

        public object retornaDependencia(int id)
        {
            ImovelFacade imovelFacade = ImovelFacade.getInstance();
            return imovelFacade.retornaDependencia(id);
        }

        public Object inserirFotos(List<string> values, int idImovel)
        {
            ImovelFacade ImovelFacade = ImovelFacade.getInstance();
            List<Fotos> fotos = new List<Fotos>();

            Imovel imovel = (Imovel)ImovelFacade.retornaImovel(idImovel);
            for (int i = 0; i < values.Count; i++)
            {
                Fotos foto = new Fotos();
                foto.caminho = values[i];
                foto.Imovel = imovel;
                imovel.Fotos.Add(foto);
            }
            ImovelFacade.editaImovel(imovel);

            return fotos;
        }

        private Anuncio criarAnuncio(Imovel imovel, int tipo, string descricao, string descricaocurta, double valor)
        {
            Anuncio anuncio = new Anuncio();

            anuncio.Descricao = descricao;
            anuncio.DescricaoCurta = descricaocurta;

            anuncio.DT_Cadastro = DateTime.Now;
            anuncio.St_Aprovado = false;
            anuncio.St_Ativo = true;
            anuncio.Tipo = tipo;
            anuncio.Valor = valor;

            return anuncio;
        }

        private string montardescricao(Imovel imovel)
        {
            //TODO: gerar descrição
            StringBuilder descricao = new StringBuilder();

            descricao.AppendFormat(@"");

            return descricao.ToString();
        }

        private double gerarValorImovel(Imovel imovel)
        {
            //TOOD: gerar preço do imovel
            return 0;
        }

        public Object retornaTipoImovel()
        {
            ImovelFacade ImovelFacade = ImovelFacade.getInstance();
            List<Tipo_Imovel> listTipoImovel = (List<Tipo_Imovel>)ImovelFacade.retornaTipoImoveis();

            IDictionary<int, string> tipoImovel = new Dictionary<int, string>();

            for (int i = 0; i < listTipoImovel.Count; i++)
                tipoImovel.Add(listTipoImovel[i].Id, listTipoImovel[i].descricao);

            return tipoImovel;
        }

        public Object buscaLocatarios(Logar login)
        {
            ImovelFacade _imovelFacade = ImovelFacade.getInstance();
            List<Pessoa_Papel_Imovel> locatarios = (List<Pessoa_Papel_Imovel>)_imovelFacade.retornaLocatarios(login.idPessoa);
            List<Locatario> locatariosRetorno = new List<Locatario>();

            foreach (Pessoa_Papel_Imovel locatario in locatarios)
            {
                Locatario aux = new Locatario();
                aux.id = locatario.Pessoa_Papel.Pessoa.Id;
                aux.nome = locatario.Pessoa_Papel.Pessoa.Name;
                aux.idImovel = locatario.Imovel.Id;
                aux.endereco = locatario.Imovel.Endereço;

                locatariosRetorno.Add(aux);
            }

            return locatariosRetorno;
        }

        public Object inserirReparoConserto(IDictionary<string, string> values)
        {
            ReparoConserto reparoConserto = new ReparoConserto();

            reparoConserto.dt_Pedido = DateTime.Now;
            reparoConserto.st_Aprovado = false;
            reparoConserto.descricao = values.First(p => p.Key == NomeCampoConstantes.campo_reparoDescricao).Value;
            reparoConserto.dependencia = values.First(p => p.Key == NomeCampoConstantes.campo_reparoDependencia).Value;
            reparoConserto.st_tipo = int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_reparoTipo).Value);

            Imovel imovel = (Imovel)retornaImovel(int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_reparoIdImovel).Value));
            reparoConserto.Imovel = imovel;

            PerfilFacade _perfilFacade = PerfilFacade.getInstance();
            Pessoa_Papel pessoaPapel = (Pessoa_Papel)_perfilFacade.retornaPapelLocatario(int.Parse(values.First(p => p.Key == NomeCampoConstantes.campo_reparoIdPessoa).Value));

            reparoConserto.Pessoa_Papel = pessoaPapel;
            reparoConserto.st_realizado = false;

            ImovelFacade _imovelFacade = ImovelFacade.getInstance();
            _imovelFacade.salvarReparoConserto(reparoConserto);

            return reparoConserto.Id;
        }

        public Object inserirArquivos(List<string> arquivos, int id)
        {
            ImovelFacade _imovelFacade = ImovelFacade.getInstance();
            ReparoConserto reparoConserto = (ReparoConserto)_imovelFacade.recuperarReparoConserto(id);

            reparoConserto.arquivo = arquivos[0];
            reparoConserto.arquivo1 = arquivos[1];
            reparoConserto.arquivo2 = arquivos[2];

            return _imovelFacade.atualizarReparoConserto(reparoConserto);
        }

        public Object buscarReparoConserto(int idImovel)
        {
            ImovelFacade _imovelfacade = ImovelFacade.getInstance();

            List<ReparoConserto> reparoConsertos = (List<ReparoConserto>)_imovelfacade.buscaReparoConserto(idImovel);

            List<Reparos> reparos = new List<Reparos>();

            foreach (ReparoConserto reparoConserto in reparoConsertos)
            {
                Reparos reparo = new Reparos();

                reparo.id = reparoConserto.Id;
                reparo.aprovado = reparoConserto.st_Aprovado;
                reparo.dependencia = reparoConserto.dependencia;
                reparo.tipo = reparoConserto.st_tipo == 1 ? "Reparo" : "Conserto";
                reparo.realizado = reparoConserto.st_realizado;

                reparos.Add(reparo);
            }

            return reparos;
        }

        public Object acaorealizado(int id)
        {
            ImovelFacade _imovelFacade = ImovelFacade.getInstance();
            ReparoConserto reparoConserto = (ReparoConserto)_imovelFacade.recuperarReparoConserto(id);

            reparoConserto.st_realizado = true;

            return _imovelFacade.atualizarReparoConserto(reparoConserto);            
        }

        public Object buscaDono(Logar login)
        {
            ImovelFacade _imovelFacade = ImovelFacade.getInstance();
            List<Pessoa_Papel_Imovel> locatarios = (List<Pessoa_Papel_Imovel>)_imovelFacade.buscaImoveisDono(login.idPessoa);
            List<Locatario> locatariosRetorno = new List<Locatario>();

            foreach (Pessoa_Papel_Imovel locatario in locatarios)
            {
                Locatario aux = new Locatario();
                //aux.id = locatario.Pessoa_Papel.Pessoa.Id;
                //aux.nome = locatario.Pessoa_Papel.Pessoa.Name;
                aux.idImovel = locatario.Imovel.Id;
                aux.endereco = locatario.Imovel.Endereço;

                locatariosRetorno.Add(aux);
            }

            return locatariosRetorno;
        }
    }
}
